Tracks 1-48

Column 1 tbl

Worst Tracks

Track WR Diff.
Music Park 3DS 12.572
Tick-Tock Clock DS 12.516
Cheese Land GBA 12.431
Dolphin Shoals 12.241
Wario Stadium DS 12.201
Rainbow Road 12.163
Bone-Dry Dunes 12.109

Best Tracks

Track WR Diff.
Rainbow Road N64 6.383
Sweet Sweet Canyon 6.871
Toad’s Turnpike N64 7.236
Mario Circuit GBA 7.294
Moo Moo Meadows 7.498
Thwomp Ruins 7.688
Yoshi Valley N64 7.787

Most Improved since Feb. 2022

Track Improvement
Dry Dry Desert GCN 13.782
Music Park 3DS 10.496
Hyrule Circuit 10.394
Ice Ice Outpost 9.688
Donut Plains 3 SNES 9.645
Piranha Plant Slide 3DS 8.888
Tick-Tock Clock DS 8.568

Column 2

PBs vs WRs

Track PB Date PB WR Diff
Mushroom Mario Kart Stadium 2022-08-14 1M 45.158S 10.446
Water Park 2022-08-14 1M 48.01S 7.826
Sweet Sweet Canyon 2022-08-17 1M 55.716S 6.871
Thwomp Ruins 2022-07-23 1M 56.663S 7.688
Flower Mario Circuit 2022-08-17 1M 53.422S 8.091
Toad Harbor 2022-08-17 2M 12.859S 10.521
Twisted Mansion 2022-08-14 2M 4.604S 10.144
Shy Guy Falls 2022-08-15 2M 7.893S 11.685
Star Sunshine Airport 2022-08-15 2M 9.102S 10.999
Dolphin Shoals 2022-08-15 2M 5.647S 12.241
Electrodrome 2022-08-15 2M 7.453S 11.488
Mount Wario 2022-08-31 1M 51.45S 9.467
Special Cloudtop Cruise 2022-08-17 2M 11.339S 11.553
Bone-Dry Dunes 2022-09-03 1M 59.021S 12.109
Bowser’s Castle 2022-08-17 2M 9.397S 10.402
Rainbow Road 2022-08-17 2M 11.477S 12.163
Shell Moo Moo Meadows 2022-08-17 1M 31.958S 7.498
Mario Circuit GBA 2022-09-02 1M 31.131S 7.294
Cheep Cheep Beach DS 2022-08-17 1M 56.547S 9.499
Toad’s Turnpike N64 2022-08-17 1M 53.609S 7.236
Banana Dry Dry Desert GCN 2022-09-02 2M 5.475S 11.851
Donut Plains 3 SNES 2022-08-31 1M 23.495S 10.662
Royal Raceway N64 2022-08-17 2M 7.086S 11.432
DK Jungle 3DS 2022-08-14 2M 12.646S 11.470
Leaf Wario Stadium DS 2022-08-14 2M 3.195S 12.201
Sherbet Land GCN 2022-09-02 1M 58.752S 11.754
Music Park 3DS 2022-07-03 2M 3.551S 12.572
Yoshi Valley N64 2022-08-14 2M 6.218S 7.787
Lightning Tick-Tock Clock DS 2022-08-14 1M 54.861S 12.516
Piranha Plant Slide 3DS 2022-08-14 2M 9.61S 10.386
Grumble Volcano Wii 2022-08-19 2M 4.488S 11.300
Rainbow Road N64 2022-08-14 1M 26.372S 6.383
Egg Yoshi Circuit GCN 2022-08-14 1M 54.189S 12.051
Excitebike Arena 2022-08-18 1M 50.425S 10.438
Dragon Driftway 2022-08-19 1M 50.088S 9.468
Mute City 2022-07-17 2M 0.105S 8.827
Triforce Wario’s Gold Mine Wii 2022-08-15 2M 10.678S 8.136
Rainbow Road SNES 2022-08-18 1M 34.172S 7.904
Ice Ice Outpost 2022-09-05 1M 55.067S 9.851
Hyrule Circuit 2022-08-18 1M 57.341S 9.666
Crossing Baby Park GCN 2022-08-15 1M 10.013S 7.871
Cheese Land GBA 2022-09-02 1M 54.367S 12.431
Wild Woods 2022-08-18 1M 54.225S 8.212
Animal Crossing 2022-08-17 1M 45.158S 8.456
Bell Neo Bowser City 3DS 2022-09-03 1M 54.095S 11.524
Ribbon Road GBA 2022-08-14 1M 54.584S 9.197
Super Bell Subway 2022-08-15 1M 51.517S 11.027
Big Blue 2022-08-14 1M 32.2S 8.617

Column 2 violin

PB Time Distributions, Feb 01, 2022 - Present

Tracks 49-96

Column 1 tbl

Worst Tracks

Track WR Diff.
Mushroom Gorge 13.592
Mario Circuit 3 12.007
Sky-High Sundae 11.817
Snow Land 11.622
Waluigi Pinball 11.305
Sydney Sprint 10.917
Shroom Ridge 10.367

Best Tracks

Track WR Diff.
Tokyo Blur 6.361
Toad Circuit 3DS 7.731
Paris Promenade 8.417
Sky Garden 9.054
Choco Mountain 9.375
Ninja Hideaway 9.431
New York Minute 9.488

Most Improved

Track Improvement
Mushroom Gorge 19.554
Waluigi Pinball 18.962
Ninja Hideaway 15.676
Snow Land 12.027
Paris Promenade 10.633
Shroom Ridge 10.114
Sky Garden 9.998

Column 2 tbl

PBs vs WRs

Track PB Date PB WR Diff
Golden Dash Paris Promenade 2022-08-14 1M 58.784S 8.417
Toad Circuit 3DS 2022-08-14 1M 28.148S 7.731
Choco Mountain 2022-08-14 2M 2.045S 9.375
Coconut Mall 2022-08-14 1M 51.731S 9.964
Lucky Cat Tokyo Blur 2022-08-14 1M 32.191S 6.361
Shroom Ridge 2022-08-14 1M 55.359S 10.367
Sky Garden 2022-08-14 1M 36.277S 9.054
Ninja Hideaway 2022-06-19 2M 2.145S 9.431
Turnip New York Minute 2022-08-14 1M 32.608S 9.488
Mario Circuit 3 2022-08-14 1M 43.171S 12.007
Kalimari Desert 2022-08-14 1M 39.011S 9.507
Waluigi Pinball 2022-08-06 2M 30.8S 11.305
Propeller Sydney Sprint 2022-08-11 2M 11.751S 10.917
Snow Land 2022-08-06 1M 38.503S 11.622
Mushroom Gorge 2022-08-06 1M 41.276S 13.592
Sky-High Sundae 2022-08-04 2M 7.354S 11.817

Column 3 violin

PB Time Distributions, March 18, 2022 - Present

Overall

Column 1

Number of PBs by Week

Average Improvement by Week

Cumulative Time Save

Column 2

Oldest PBs

Track PB Date
Ninja Hideaway 2022-06-19
Music Park 3DS 2022-07-03
Mute City 2022-07-17
Thwomp Ruins 2022-07-23
Sky-High Sundae 2022-08-04
Waluigi Pinball 2022-08-06
Snow Land 2022-08-06

Largest PBs

Track Date Improvement
Mushroom Gorge 2022-08-04 8.688
Waluigi Pinball 2022-08-04 7.572
Waluigi Pinball 2022-08-04 6.131
New York Minute 2022-08-04 4.835
Mushroom Gorge 2022-08-06 4.630
Sydney Sprint 2022-08-04 4.317
Snow Land 2022-08-06 4.058

Smallest PBs

Track Date Improvement
Hyrule Circuit 2022-03-16 0.005
Piranha Plant Slide 3DS 2022-02-09 0.007
Choco Mountain 2022-03-19 0.012
Twisted Mansion 2022-03-12 0.019
Bone-Dry Dunes 2022-05-26 0.020
Ice Ice Outpost 2022-09-05 0.020
Shroom Ridge 2022-03-19 0.023

Column 3

Newest PBs

Track Date Improvement
Ice Ice Outpost 2022-09-05 0.619
Ice Ice Outpost 2022-09-05 0.020
Bone-Dry Dunes 2022-09-03 1.163
Neo Bowser City 3DS 2022-09-03 1.234
Sherbet Land GCN 2022-09-02 1.070
Cheese Land GBA 2022-09-02 0.742
Cheese Land GBA 2022-09-02 0.349
Mario Circuit GBA 2022-09-02 1.190
Dry Dry Desert GCN 2022-09-02 0.228
Dry Dry Desert GCN 2022-09-02 0.355
Mount Wario 2022-08-31 1.166
Donut Plains 3 SNES 2022-08-31 0.256
Donut Plains 3 SNES 2022-08-31 0.437
Donut Plains 3 SNES 2022-08-31 0.138
Dry Dry Desert GCN 2022-08-22 0.163
Dragon Driftway 2022-08-19 1.111
Dragon Driftway 2022-08-19 0.042
Grumble Volcano Wii 2022-08-19 1.628
Cheese Land GBA 2022-08-18 0.457
Dry Dry Desert GCN 2022-08-18 1.175
Dry Dry Desert GCN 2022-08-18 0.155
Dry Dry Desert GCN 2022-08-18 0.351
Bone-Dry Dunes 2022-08-18 0.888
Rainbow Road SNES 2022-08-18 0.204
Excitebike Arena 2022-08-18 0.602
Neo Bowser City 3DS 2022-08-18 0.407
Wild Woods 2022-08-18 0.142
Hyrule Circuit 2022-08-18 0.774
Moo Moo Meadows 2022-08-17 0.624
Animal Crossing 2022-08-17 0.491
Rainbow Road 2022-08-17 0.609
Royal Raceway N64 2022-08-17 0.220
Sweet Sweet Canyon 2022-08-17 1.242
Donut Plains 3 SNES 2022-08-17 0.228
Donut Plains 3 SNES 2022-08-17 0.760
Donut Plains 3 SNES 2022-08-17 0.170
Donut Plains 3 SNES 2022-08-17 0.278
Cloudtop Cruise 2022-08-17 0.684
Mario Circuit 2022-08-17 0.553
Toad Harbor 2022-08-17 0.504
Toad’s Turnpike N64 2022-08-17 0.286
Cheep Cheep Beach DS 2022-08-17 0.162
Bowser’s Castle 2022-08-17 0.531
Electrodrome 2022-08-15 1.064
Dolphin Shoals 2022-08-15 0.237
Sunshine Airport 2022-08-15 0.654
Dragon Driftway 2022-08-15 0.914
Wario’s Gold Mine Wii 2022-08-15 1.571
Super Bell Subway 2022-08-15 0.089
Baby Park GCN 2022-08-15 0.799
---
title: "Mario Kart Time Trial PBs 150cc"
output:
  flexdashboard::flex_dashboard:
    orientation: columns
    theme: sandstone
    navbar:
      - { title: "Speedruns", href: "sr.html", align: right}
      - { icon: "fas fa-home", href: "index.html", align: right}
    favicon: blueshell.png
    source_code: embed
---

<script>
$(document).ready(function(){
    $('[data-toggle="popover"]').popover(); 
});
</script>

```{r lib}
library(tidyverse)
library(rvest)
library(plotly)
library(lubridate)
library(knitr)
library(kableExtra)
```

```{r scrapeWRs}
html <- read_html("http://www.mkwrs.com/mk8dx/wrs.php")

ttwr0 <- html %>% html_elements(".wr") %>% html_table() %>% .[[1]]
```


```{r import}
abr <- read_csv("_data/track-abbr.csv")

tt <- read_csv("_data/time-trials.csv",
               col_types = cols(total = "c")) %>%
  filter(cc == 150) %>%
  mutate(
    total = ms(total),
    yr = year(date),
    mth = month(date),
    day = day(date),
    hour = hour(time),
    min = minute(time),
    dt = make_datetime(
      year = yr,
      month = mth,
      day = day,
      hour = hour,
      min = min
    )
  ) %>%
  left_join(abr)

ttwr <- ttwr0 %>% 
  select(track = Track, total = `Time+Video`) %>% 
  filter(track != "Total:") %>% 
  distinct() %>% 
  mutate(total = str_replace_all(total, "'", ":"),
         total = str_replace_all(total, "\"", "."),
         total = ms(total)) %>% 
  left_join(abr, by = c("track" = "lss")) %>% 
  select(trk, total)
```


```{r makeVars}
ttDiff <- tt %>% 
  arrange(trk, dt) %>% 
  group_by(trk) %>% 
  mutate(prev = lag(total), .after = total,
         diff = as.double(prev - total, units = "secs"),
         diff = replace_na(diff, 0)
         ) %>% 
  mutate(cumsum = cumsum(diff), .after = diff) 

wk <- ttDiff %>% 
  filter(!is.na(prev)) %>% 
  ungroup() %>% 
  mutate(week = (week(date)-4)) %>% 
  group_by(week) %>% 
  summarise(mean = mean(diff), n = n()) %>% 
  add_row(week=16, mean=0, n=0, .after = 15)

wr <- ttDiff %>% 
  slice_max(dt) %>% 
  ungroup() %>% 
  arrange(trkNO) %>% 
  left_join(ttwr, by = "trk") %>% 
  select(date, track, total.x, cumsum, cup, type, total.y) %>% 
  mutate(diff = as.double(total.x - total.y, units = "secs"))
```

# Tracks 1-48 

## Column 1 tbl {data-width="320"}

### Worst Tracks

```{r worst48}
wr %>% 
  filter(!str_starts(type, "wave")) %>% 
  select(track, diff) %>% 
  arrange(desc(diff)) %>% 
  head(7) %>% 
  kable(
    col.names = c('track' = 'Track',
    'diff' = 'WR Diff.')
  ) %>% 
  kable_styling()
```

### Best Tracks

```{r best48}
wr %>% 
  filter(!str_starts(type, "wave")) %>% 
  select(track, diff) %>% 
  arrange(diff) %>% 
  head(7) %>% 
  kable(
    col.names = c('track' = 'Track',
    'diff' = 'WR Diff.')
  ) %>% 
  kable_styling()
```

### Most Improved since Feb. 2022

```{r mostImprv48}
wr %>% 
  filter(!str_starts(type, "wave")) %>% 
  select(track, cumsum) %>% 
  arrange(desc(cumsum)) %>% 
  head(7) %>% 
  kable(
    col.names = c('track' = 'Track',
    'cumsum' = 'Improvement')
  ) %>% 
  kable_styling()
```

## Column 2

### PBs vs WRs

```{r}
wr2 <- wr %>%
  filter(!str_starts(type, "wave")) %>% 
  select(cup, track, date, total.x, total.y, diff) 

wr2 %>%
  kbl(
    col.names = c(" ", "Track", "PB Date", "PB", "WR", "WR Diff"),
    align = "c",
    escape = FALSE
  ) %>%
  kable_styling(full_width = TRUE) %>%
  column_spec(column = 1,
              extra_css = 'transform: rotate(270deg);') %>%
  column_spec(3:4,
              extra_css = 'font-size: 80%;') %>%
  column_spec(
    6,
    color = "white",
    background = spec_color(
      wr2$diff,
      begin = 0.3,
      end = 0.7,
      alpha = 0.7,
      option = "A"
    ),
    popover = paste0("WR: ", wr2$total.y)
  ) %>%
  remove_column(5) %>%
  collapse_rows(columns = 1,
                row_group_label_position = 'stack') %>%
  row_spec(0, align = "c")
```

## Column 2 violin

### PB Time Distributions, Feb 01, 2022 - Present

```{r violin48, fig.height=10}
tt48 <- tt %>% 
  filter(trkNO <= 48) %>%
  mutate(track = fct_reorder(track, trkNO))

ggtt <- tt48 %>% 
  filter(trk != "dBP") %>% 
  group_by(track) %>% 
  mutate(sd = sd(total)) %>% 
  ungroup() %>% 
  ggplot(aes(factor(track), total)) +
  geom_violin(draw_quantiles = 0.5, 
              scale = "width",
              aes(fill = sd, color=sd),
              alpha = .7) + 
  stat_summary(fun = "median", geom = "point", size = .4) +
  scale_fill_gradient(low = "darkcyan", high = "plum") +
  scale_color_gradient(low = "darkcyan", high = "plum") +
  scale_y_time() +
  scale_x_discrete(limits = rev(levels(tt48$track))) +
  coord_flip() +
  labs(x = "",
       y = "PB Time") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45,
                                   hjust = 0.98,
                                   vjust = 0.9),
        axis.text = element_text(size = 8),
        axis.ticks = element_line(size = .2),
        panel.grid = element_line(size = .2),
        panel.border = element_rect(fill = NA, size = .2),
        legend.position = "none")

ggplotly(ggtt)
```

# Tracks 49-96 

## Column 1 tbl {data-width="320"}

### Worst Tracks

```{r worst96}
wr %>% 
  filter(str_starts(type, "wave")) %>% 
  select(track, diff) %>% 
  arrange(desc(diff)) %>% 
  head(7) %>% 
  kable(
    col.names = c('track' = 'Track',
    'diff' = 'WR Diff.')
  ) %>% 
  kable_styling()
```

### Best Tracks

```{r best96}
wr %>% 
  filter(str_starts(type, "wave")) %>% 
  select(track, diff) %>% 
  arrange(diff) %>% 
  head(7) %>% 
  kable(
    col.names = c('track' = 'Track',
    'diff' = 'WR Diff.')
  ) %>% 
  kable_styling()
```

### Most Improved 

```{r mostImprv96}
wr %>% 
  filter(str_starts(type, "wave")) %>% 
  select(track, cumsum) %>% 
  arrange(desc(cumsum)) %>% 
  head(7) %>% 
  kable(
    col.names = c('track' = 'Track',
    'cumsum' = 'Improvement')
  ) %>% 
  kable_styling()
```

## Column 2 tbl

### PBs vs WRs

```{r}
PBw <- wr %>%
  filter(str_starts(type, "wave")) %>%
  select(cup, track, date, total.x, total.y, diff)

PBw %>%
  kbl(
    col.names = c(" ", "Track", "PB Date", "PB", "WR", "WR Diff"),
    align = "c"
  ) %>%
  kable_styling(full_width = TRUE) %>%
  column_spec(column = 1,
              extra_css = 'transform: rotate(270deg);') %>%
  column_spec(3:4,
              extra_css = 'font-size: 80%;') %>%
  column_spec(
    6,
    color = "white",
    background = spec_color(
      PBw$diff,
      begin = 0.3,
      end = 0.7,
      alpha = 0.7,
      option = "A"
    ),
    popover = paste0("WR: ", PBw$total.y)
  ) %>%
  remove_column(5) %>%
  collapse_rows(columns = 1,
                row_group_label_position = 'stack') %>%
  row_spec(0, align = "c")
```

## Column 3 violin

### PB Time Distributions, March 18, 2022 - Present

```{r fig.height=10}
tt96 <- tt %>% 
  filter(trkNO > 48) %>%
  mutate(track = fct_reorder(track, trkNO))

gg96tt <- tt96 %>% 
  group_by(track) %>% 
  mutate(sd = sd(total)) %>% 
  ungroup() %>% 
  ggplot(aes(factor(track), total)) +
  geom_violin(draw_quantiles = 0.5, 
              scale = "width",
              aes(fill = sd, color=sd),
              alpha = .7) + 
  stat_summary(fun = "median", geom = "point", size = .4) +
  scale_y_time() +
  scale_fill_gradient(low = "darkcyan", high = "plum") +
  scale_color_gradient(low = "darkcyan", high = "plum") +
  scale_x_discrete(limits = rev(levels(tt96$track))) +
  coord_flip() +
  labs(x = "",
       y = "PB Time") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45,
                                   hjust = 0.98,
                                   vjust = 0.9),
        axis.text = element_text(size = 8),
        axis.ticks = element_line(size = .2),
        panel.grid = element_line(size = .2),
        panel.border = element_rect(fill = NA, size = .2),
        legend.position = "none")

ggplotly(gg96tt)
```

# Overall

## Column 1

### Number of PBs by Week

```{r ggPBwk}
ggN <- wk %>% 
  ggplot() +
  geom_line(aes(x=week, y=n)) +
  theme_minimal() +
  labs(y = "PBs",
       x = "Week")

ggplotly(ggN)
```

### Average Improvement by Week

```{r ggAvgImprv}
ggWk <- wk %>% 
  ggplot(aes(x=week, y=mean)) +
  geom_line() +
  theme_minimal() + 
  labs(x = "Week",
       y = "Average Time Save (secs)")

ggplotly(ggWk)
```

### Cumulative Time Save

```{r}
CTS <- ttDiff %>% 
  ungroup() %>% 
  filter(!is.na(prev)) %>% 
  arrange(dt) %>% 
  mutate(cumsum = cumsum(diff))
  
ggCTS <- CTS %>% 
  ggplot(aes(x=dt, y=cumsum)) +
  geom_step() +
  theme_minimal() +
  labs(x="", y="Cumulative Time Saved (secs)") +
  theme(axis.text.x = element_text(angle = 90),
        legend.position = "none")

ggplotly(ggCTS)
```

## Column 2 {data-width="420"}

### Oldest PBs

```{r old}
wr %>% 
  select(track, date) %>% 
  arrange(date) %>% 
  head(7) %>% 
  kable(
    col.names = c('track' = 'Track',
    'date' = 'PB Date')
  ) %>% 
  kable_styling()
```

### Largest PBs

```{r}
ttDiff %>%
  ungroup() %>% 
  select(track, date, diff) %>% 
  arrange(desc(diff)) %>% 
  head(7) %>% 
  kable(
    col.names = c(
      'track' = 'Track',
      'date' = 'Date',
      'diff' = 'Improvement')
  ) %>% 
  kable_styling()
```

### Smallest PBs

```{r}
ttDiff %>%
  ungroup() %>% 
  select(track, date, diff) %>% 
  filter(diff != 0) %>% 
  arrange(diff) %>% 
  head(7) %>% 
  kable(
    col.names = c(
      'track' = 'Track',
      'date' = 'Date',
      'diff' = 'Improvement')
  ) %>% 
  kable_styling()
```

## Column 3 {data-width="420"}

### Newest PBs

```{r newest}
ttDiff %>%
  ungroup() %>% 
  select(track, date, diff, dt) %>% 
  slice_max(dt, n=50) %>% 
  select(-dt) %>% 
  kable(
    col.names = c(
      'track' = 'Track',
      'date' = 'Date',
      'diff' = 'Improvement')
  ) %>% 
  kable_styling()
```